package structure

import (
	"fmt"
	"math"

	"gddgame.cc/galaxy/utils"
)

type SortedStruct struct {
}

func (execute *Execute) GetSortedExtend(conn SafeConn, data Data, et ExtendType, min int, max int, asc bool) SortedDataSlice {
	key := execute.GetExtendKey(data, et)
	var minKey interface{}
	var maxKey interface{}
	if min == math.MinInt64 {
		minKey = "-inf"
	} else {
		minKey = min
	}
	if max == math.MaxInt64 {
		maxKey = "+inf"
	} else {
		maxKey = max
	}
	var c interface{}
	if asc {
		c, _ = conn.Do("ZRANGEBYSCORE", key, minKey, maxKey, "WITHSCORES")
	} else {
		c, _ = conn.Do("ZREVRANGEBYSCORE", key, maxKey, minKey, "WITHSCORES")
	}
	if c == nil {
		return nil
	}
	cc := c.([]interface{})
	es := make([]*SortedData, 0, len(cc))
	for i := 0; i < len(cc); i += 2 {
		k := utils.ToBytes(utils.ToString(cc[i]))
		v := utils.ToString(cc[i+1])
		es = append(es, &SortedData{Value: k, Score: utils.ToInt(v)})
	}
	return es
}

func (execute *Execute) AddSortedExtend(conn SafeConn, data Data, et ExtendType, extend []*SortedData) {
	m := make([]interface{}, 0, len(extend)+1)
	for _, s := range extend {
		m = append(m, s.Score, s.Value)
	}
	args := append([]interface{}{execute.GetExtendKey(data, et)}, m...)
	_ = conn.Send("ZADD", args...)
}

func (execute *Execute) ResetSortedExtend(conn SafeConn, data Data, et ExtendType, extend []*SortedData) {
	key := execute.GetExtendKey(data, et)
	_ = conn.Send("DEL", key)
	if extend != nil {
		m := make([]interface{}, 0, len(extend)+1)
		m = append(m, key)
		for _, s := range extend {
			m = append(m, s.Score, s.Value)
		}
		args := append([]interface{}{}, m...)
		_ = conn.Send("ZADD", args...)
	}
}

func (execute *Execute) RemoveSortedExtend(conn SafeConn, data Data, et ExtendType, extend []interface{}) {
	args := append([]interface{}{execute.GetExtendKey(data, et)}, extend...)
	_ = conn.Send("ZREM", args...)
}

func (execute *Execute) ClearSortedExtend(conn SafeConn, data Data, et ExtendType, min int, max int) {
	var minKey interface{}
	var maxKey interface{}
	if min == math.MinInt32 {
		minKey = "-inf"
	} else {
		minKey = min
	}
	if max == math.MaxInt32 {
		maxKey = "+inf"
	} else {
		maxKey = max
	}
	_ = conn.Send("ZREMRANGEBYSCORE", execute.GetExtendKey(data, et), minKey, maxKey)
	//r, err := conn.Do("ZREMRANGEBYSCORE", execute.GetExtendKey(data, et), minKey, maxKey)
	//if err != nil {
	//	return 0
	//}
	//return utils.ToInt(r)
}

func (execute *Execute) RankSortedExtend(conn SafeConn, data Data, et ExtendType, member interface{}) int {
	key := execute.GetExtendKey(data, et)
	c, _ := conn.Do("ZREVRANK", key, member)
	if c == nil {
		return 0
	}
	// 第一名是0，直接加1
	return utils.ToInt(c) + 1
}

func (execute *Execute) ScoreSortedExtend(conn SafeConn, data Data, et ExtendType, member interface{}) int {
	key := execute.GetExtendKey(data, et)
	c, _ := conn.Do("ZSCORE", key, member)
	if c == nil {
		return 0
	}
	// 第一名是0，直接加1
	return utils.ToInt(utils.ToString(c))
}

func (execute *Execute) RemoveRangSortedExtend(conn SafeConn, data Data, et ExtendType, score interface{}) {
	key := execute.GetExtendKey(data, et)
	_ = conn.Send("ZREMRANGEBYSCORE", key, "-inf", score)
}

func (execute *Execute) GetSortedData(b []byte) *SortedData {
	e := &SortedData{}
	_, err := e.UnmarshalMsg(b)
	if err != nil {
		fmt.Println("get sort", err)
	}

	return e
}
